'use strict';
import React, {Component} from 'react';
import {
    Text,
    View,
    Modal,
    ActivityIndicator,
} from 'react-native';
import * as Color from "../constant/Color";
import {UUID} from "../util/UUID";
import L from "../util/L";
import * as ToastAndroid from "react-native/Libraries/Components/ToastAndroid/ToastAndroid.android";

/** 网络请求框架 */
export default class HttpHelper extends Component {
    static POST :string = 'POST';
    static GET  :string = 'GET';

    static RESPONSE_SUCCESS :number = 200;
    static RESPONSE_FAIL    :number = -1;

    /** URL */
    mUrl        :string;
    /** Post/Get */
    mMethod     :string = HttpHelper.POST;
    /** 头参数 */
    mHeadParam  = new Map();
    /** body参数 */
    mBodyParam  = new Map();
    /** 请求序列号 */
    mRequestId  :string = UUID.getOne();
    /** 回调监听器 */
    mListener   :Function;
    /** 超时 */
    mTimeOut    :Number = 30 * 1000;
    /** 是否取消 */
    mIsCancel   :boolean = false;
    /** 是否正在请求 */
    mIsLoading  :boolean = false;

    constructor(props) {
        super(props);
        this.state = {
            /** 是否显示加载界面(是否占用界面) */
            isShowProg: false,
            /** 提示信息 */
            notiInfo:   "",
        }
    }

    render() {
        if(this.state.isShowProg){
            return (
                <Modal
                    animationType   = {'fade'}
                    transparent     = {true}
                    visible         = {true}
                    backdropPressToClose = {false}
                    onRequestClose  = {() => this._setIsShowDialog(false)}
                    onClosed        = {() => this._onModalClose()}>

                    <View style={{flex:1, flexDirection:'column', justifyContent:'center', alignItems:'center', backgroundColor: 'rgba(0, 0, 0, 0.5)',}}>
                        <View
                            style={{justifyContent:'center', alignItems:'center', padding:20, backgroundColor: Color.windowWhite, borderRadius:5}}>
                            <ActivityIndicator
                                animating={this.state.isShow}
                                size="large" />
                            <Text style={{marginTop:5, display:!!this.state.notiInfo ? "flex" : "none"}} >{this.state.notiInfo}</Text>
                        </View>
                    </View>
                </Modal>
            );
        }
        else return <View/>
    }

    /** 设置URL */
    setURL(url:string):HttpHelper{
        if(!url) return this;
        this.mUrl = url;
        return this;
    }

    /** 设置请求方式 */
    setMethod(method:string):HttpHelper{
        if(!(method === HttpHelper.POST || method === HttpHelper.GET)) this.mMethod = HttpHelper.POST;
        else this.mMethod = method;
        return this;
    }

    /** 设置展示信息 */
    setNotiInfo(noti:string):HttpHelper{
        if(!noti) return this;
        this.setState({
            notiInfo: noti,
        });
        return this;
    }

    /** 设置头参数 */
    setHeadParams(param:Map<string, string>):HttpHelper{
        if(!param) return this;
        this.mHeadParam = param;
        return this;
    }

    /** 设置BODY参数 */
    setBodyParams(param:Map<string, string>):HttpHelper{
        if(!param) return this;
        // if(!param || !(param instanceof Map)) return this;
        this.mBodyParam = param;
        return this;
    }

    /** 设置RequestId(方便回调) */
    setRequestId(request:string):HttpHelper{
        if(!request) return this;
        this.mRequestId = request;
        return this;
    }

    /** 设置回调监听器 */
    setListener(listener:Function):HttpHelper{
        if(!listener) return this;
        this.mListener = listener;
        return this;
    }

    /** 设置超时 */
    setTimeout(timeout:number):HttpHelper{
        if(timeout <= 0) this.mTimeOut = (30 * 1000);
        else this.mTimeOut = timeout;
        return this;
    }

    /** 控制是否显示 */
    _setIsShowDialog(isShow:boolean):HttpHelper{
        this.setState({
            isShowProg: isShow,
        });
        return this;
    }

    /**
     * 开始查询
     * @param isShowDialog  是否显示界面
     */
    start(isShowDialog:boolean):void{
        if(!this.mUrl || this.mUrl === '' || this.mIsLoading) return;
        this.setState({
            isShowProg: isShowDialog,
        });
        this.mIsLoading = true;

        let body = this.strMapToObj(this.mBodyParam);
        if(this.mHeadParam.has("Content-Type") && this.mHeadParam.get("Content-Type") === ("application/json")){
            body = JSON.stringify(this.strMapToObj(this.mBodyParam));
        }
        console.log("----------------body--------------");
        console.log(body);

        let header = this.strMapToObj(this.mHeadParam);
        console.log("----------------header--------------");
        console.log(header);

        fetch(
            // url
            this.mMethod === HttpHelper.POST
                ?
                this.mUrl
                :
                HttpHelper.getGetUrlWithParams(this.mUrl, this.mBodyParam),

            // config
            this.mMethod === HttpHelper.POST
                ?
                {
                    method: this.mMethod,
                    headers:header,
                    body: body,  // GET/Head请求不允许body存在
                    timeout: this.mTimeOut,
                }
                :
                {
                    method: this.mMethod,
                    headers:header,
                    timeout: this.mTimeOut,
                }
            )
            .then((response) => {
                this.mIsLoading = false;
                this._setIsShowDialog(false);
                if(this.mIsCancel){
                    this.mIsCancel = false;
                    return;
                }

                return response.text();  //将返回结果转换成文本
                // return response.json();  //将返回结果转换成json(正常都是这个)
            })
            .then((res) => {
                L.logOnly('[成功]查询返回：' + res);

                if(!this.mListener) return;
                let resObj = JSON.parse(res);
                if(resObj.code === 200 || resObj.code === 0) this.mListener(HttpHelper.RESPONSE_SUCCESS, resObj);
                else {
                    ToastAndroid.show(resObj.msg, ToastAndroid.SHORT);
                    this.mListener(HttpHelper.RESPONSE_FAIL, resObj);
                }
            })
            .catch((error) => {
                L.logOnly('[失败]查询返回：' + error);
                if(error.toString())ToastAndroid.show(error.toString(),ToastAndroid.SHORT);
                this.mIsLoading = false;
                this._setIsShowDialog(false);
                if(this.mIsCancel){
                    this.mIsCancel = false;
                    return;
                }
                if(this.mListener && error.toString())this.mListener(HttpHelper.RESPONSE_FAIL, error.toString());
            });
    }

    /** modal消失回调 */
    _onModalClose():void{
        if(!this.mIsLoading) return;
        this.mIsCancel = true;
    }

    /** 获取get的URL(包含参数) */
    _getGetParamUrl():string{
        let url = this.mUrl;
        if(!this.mBodyParam || this.mBodyParam.size === 0) return url;

        let paramsArray = Array.of();
        //拼接参数
        Object.keys(this.mBodyParam).forEach(key => paramsArray.push(key + '=' + this.mBodyParam[key]));
        if (url.search(/\?/) === -1) {
            url += '?' + paramsArray.join('&')
        } else {
            url += '&' + paramsArray.join('&')
        }
        L.logOnly('URL-----[GET]：' + url);
        return url;
    }


    static getGetUrlWithParams(url,map):string{
        if (!map) return url;
        for(let [key, value] of map){
            let item = (key + "=" + value);
            if (url.search(/\?/) === -1) {
                url += ('?' + item);
            } else {
                url += ('&' + item);
            }
        }
        url = encodeURI(url);
        L.logOnly('URL2-----[GET]：' + url);
        return url;
    }

    /** Map 转为对象 */
    strMapToObj(strMap):Object {
        let obj = Object.create(null);
        for (let [k,v] of strMap) {
            obj[k] = v;
        }
        return obj;
    }
}

